/**
 * 
 */
package com.geezdata.cps.ttk.common.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.geezdata.cps.base.enums.ErrorCode;
import com.geezdata.cps.base.exceptions.MyException;
import com.geezdata.cps.base.vo.SendModeVO;
import com.geezdata.cps.ttk.common.constants.TimeUnitConstants;

/**
 * @author sszheng
 * @date 创建时间：2017年11月9日 下午2:48:28
 *
 */
public class CronExpressionUtil {
	private static final Logger logger = LoggerFactory.getLogger(CronExpressionUtil.class);
	
	public static String getCronExpression(SendModeVO sendModeVO) {
		if(sendModeVO.getSendType() != 3 || sendModeVO.getStartTime() == null || StringUtils.isEmpty(sendModeVO.getExecutionCycleUnit()) ){
			throw new MyException(ErrorCode.INVALID_PARAMS);
		}
		int week = getWeek(sendModeVO.getStartTime());
		String df = getDateFormat(sendModeVO.getExecutionCycle(), sendModeVO.getExecutionCycleUnit(), week);
		String cronExpression = formatDateByPattern(sendModeVO.getStartTime(), df);
		if(!CronExpression.isValidExpression(cronExpression)){
			logger.error("error cron expression: " + cronExpression);
			throw new MyException(ErrorCode.INVALID_PARAMS);
		}
		return cronExpression;
	}
	
	private static int getWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_WEEK);
	}
	
	private static String getDateFormat(Integer executionCycle, String executionCycleUnit, int week) {
		String dateFormat = "";
		switch (executionCycleUnit) {
		case TimeUnitConstants.SECONDS:
			dateFormat = "*/" + executionCycle + " * * * * ? *";
			break;
		case TimeUnitConstants.MINUTE:
			dateFormat = "ss */" + executionCycle +" * * * ? *";
			break;
		case TimeUnitConstants.HOUR:
			dateFormat = "ss mm */" + executionCycle + " * * ? *";
			break;
		case TimeUnitConstants.DAY:
			dateFormat = "ss mm HH */" + executionCycle + " * ? *";
			break;
		case TimeUnitConstants.MONTH:
			dateFormat = "ss mm HH dd */" + executionCycle + " ? *";
			break;
		case TimeUnitConstants.WEEK:
			if(executionCycle != 1) {
				throw new MyException(ErrorCode.INVALID_PARAMS);
			}
			dateFormat = "ss mm HH ? * " + week + " *";
			break;
		case TimeUnitConstants.YEAR:
			dateFormat = "ss mm HH dd MM ? yyyy/" + executionCycle;
			break;
		default:
			throw new MyException(ErrorCode.INVALID_PARAMS);
		}
		return dateFormat;
	}
	
	private static String formatDateByPattern(Date date, String dateFormat){ 
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);  
        return sdf.format(date);  
    } 
}
